Adam
使用 Adam 算法更新参数权重。支持 Nesterov 动量。
算法逻辑如下:
\[\begin{split}m_t = m_{t-1} + (g_t - m_{t-1}) \cdot (1 - \beta_1) \\ v_t = v_{t-1} + (g_t^2 - v_{t-1}) \cdot (1 - \beta_2) \\ \hat{lr} = lr \cdot \frac{\sqrt{1 - \beta_2^t}}{1 - \beta_1^t}\end{split}\]如果不启用 Nesterov:
\[w_t = w_{t-1} - \hat{lr} \cdot \frac{m_t}{\sqrt{v_t} + \epsilon}\]如果启用 Nesterov:
\[w_t = w_{t-1} - \hat{lr} \cdot \frac{m_t \cdot \beta_1 + (1 - \beta_1) \cdot g_t}{\sqrt{v_t} + \epsilon}\]
- 输入:
m - 一阶矩向量地址(输入/输出)。
v - 二阶矩向量地址(输入/输出)。
gradient - 梯度向量地址。
weight - 权重向量地址(输入/输出)。
beta1 - 一阶矩估计的指数衰减率。
beta2 - 二阶矩估计的指数衰减率。
beta1_power - \(\beta_1^t\) 的值(指针形式传入)。
beta2_power - \(\beta_2^t\) 的值(指针形式传入)。
eps - 数值稳定性项 epsilon。
learning_rate - 学习率。
nesterov - 是否启用 Nesterov 动量(0: 不启用, 1: 启用)。
start - 计算的起始索引(包含)。
end - 计算的结束索引(不包含)。
core_mask - 核掩码(仅适用于共享存储版本)。
- 输出:
m - 更新后的一阶矩。
v - 更新后的二阶矩。
weight - 更新后的权重。
- 支持平台:
FT78NEMT7004备注
仅支持 fp32 数据类型。
共享存储版本:
-
void fp_adam_s(float *m, float *v, const float *gradient, float *weight, float beta1, float beta2, float *beta1_power, float *beta2_power, float eps, float learning_rate, int nesterov, int start, int end, int core_mask)
C调用示例:
1#include <stdio.h> 2 3int main(int argc, char* argv[]) { 4 // 假设所有数据均位于DDR空间 5 float* m = (float*)0xC0000000; 6 float* v = (float*)0xC1000000; 7 float* gradient = (float*)0xC2000000; 8 float* weight = (float*)0xC3000000; 9 10 // 标量参数 11 float beta1 = 0.9f; 12 float beta2 = 0.999f; 13 float beta1_power_val = 0.9f; // beta1^1 14 float beta2_power_val = 0.999f; // beta2^1 15 float* beta1_power = &beta1_power_val; 16 float* beta2_power = &beta2_power_val; 17 float eps = 1e-8f; 18 float learning_rate = 0.001f; 19 int nesterov = 1; 20 21 int start = 0; 22 int end = 800000; // 元素总数 23 int core_mask = 0xff; // 使用所有核心 24 25 fp_adam_s(m, v, gradient, weight, beta1, beta2, beta1_power, beta2_power, 26 eps, learning_rate, nesterov, start, end, core_mask); 27 28 return 0; 29}
私有存储版本:
-
void fp_adam_p(float *m, float *v, const float *gradient, float *weight, float beta1, float beta2, float *beta1_power, float *beta2_power, float eps, float learning_rate, int nesterov, int start, int end)
C调用示例:
1#include <stdio.h> 2 3int main(int argc, char* argv[]) { 4 // 假设所有数据均位于L2/AM空间 5 float* m = (float*)0x10820000; 6 float* v = (float*)0x10830000; 7 float* gradient = (float*)0x10840000; 8 float* weight = (float*)0x10850000; 9 10 float beta1 = 0.9f; 11 float beta2 = 0.999f; 12 float beta1_power_val = 0.9f; 13 float beta2_power_val = 0.999f; 14 float eps = 1e-8f; 15 float learning_rate = 0.001f; 16 int nesterov = 0; 17 int start = 0; 18 int end = 2000; 19 20 fp_adam_p(m, v, gradient, weight, beta1, beta2, &beta1_power_val, &beta2_power_val, 21 eps, learning_rate, nesterov, start, end); 22 23 return 0; 24}